package com.leigang.swagger.config;

import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

/**
 * @author leigang
 * @description: 动态数据源切面处理
 * @date 20/8/12  22:01
 */
@Aspect
@Component
@Order(-1)
@Slf4j
public class DataSourceTypeHandle {

    @Around("execution(* com.leigang.swagger.service.impl.*.*(..))")
    @Order(1)
    public Object handleType(ProceedingJoinPoint jp)   {

        //同时支持类和方法上的注解，以方法上为主
        DataSourceType typeInClass = jp.getTarget().getClass().getAnnotation(DataSourceType.class);
        MethodSignature methodSignature = (MethodSignature) jp.getSignature();
        DataSourceType typeInMethod = methodSignature.getMethod().getDeclaredAnnotation(DataSourceType.class);

        String  name;

        if (typeInMethod != null) {
            name = typeInMethod.name();
        } else if (typeInClass != null) {
            name = typeInClass.name();
        } else {
            try {
                return  jp.proceed();
            }catch (Throwable throwable){
                log.error("异常："+throwable);
                return "";
            }

        }

        return dealWithTargetDS(jp,name);
    }


    private Object dealWithTargetDS(ProceedingJoinPoint jp,String name) {
        if (DataSourceTypeConstant.ALL_DATASOURCE.contains(name)) {
            log.info("开始切换数据源，方法{}，数据源{}",jp.getSignature().getName(),name);
            DynamicDataSourceHolder.set(name);
        } else {
            log.error("方法{}，切换非法数据源{}",jp.getSignature().getName(),name);
        }

        Object proceed ;
        try {
            proceed = jp.proceed();
        } catch (Throwable throwable) {
            log.error("异常："+throwable);
            return "";
        }finally {
            DynamicDataSourceHolder.clear();
        }

        return proceed;
    }

}
